<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:nyext="urn:noury-extensions">
  <xsl:output method="text" encoding="UTF-8"/>

  <xsl:param name="package" />
  <xsl:param name="outdir" />
  <xsl:param name="name" />
  <xsl:param name="domainName" />
  <xsl:variable name="domain" select="/manifest/types/domain[@name=$domainName]" />
  <xsl:variable name="pkdomain">
    <xsl:apply-templates select="$domain" mode="get-pk-domain" />
  </xsl:variable>

  <xsl:include href="functions.xslt" />
  
  <xsl:template name="get-imapper-name">
    <xsl:param name="domain" select="$domain" />
    <xsl:text>I</xsl:text>
    <xsl:value-of select="$domain/@name" />
    <xsl:text>Mapper</xsl:text>
  </xsl:template>

  <xsl:template name="get-icontainer-name">
    <xsl:text>I</xsl:text>
    <xsl:value-of select="$domainName" />
    <xsl:text>Container</xsl:text>
  </xsl:template>

  <xsl:template name="get-visibility">
    <xsl:choose>
      <xsl:when test="not($domain/@visibility)">
        <xsl:text>public</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <!--<xsl:text>public</xsl:text>-->
        <xsl:value-of select="$domain/@visibility" /> 
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <xsl:template match="*" mode="get-type">
    <xsl:value-of select="@type" />
    <xsl:if test="@nullable='true'">
      <xsl:text>?</xsl:text>
    </xsl:if>
  </xsl:template>
  
  <xsl:template name="get-pk-type">
    <xsl:choose>
      <xsl:when test="count(msxsl:node-set($pkdomain)/domain/pk/field) &gt; 1">
        <xsl:text>PrimaryKey.Key</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select="$domain/data/field[@name=msxsl:node-set($pkdomain)/domain/pk/field/@name]" mode="get-type" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <xsl:template match="domain" mode="get-pk-domain">
    <xsl:choose>
      <xsl:when test="@extends">
        <xsl:variable name="extends" select="@extends" />
        <xsl:apply-templates select="/manifest/types/domain[@name=$extends]" mode="get-pk-domain" />
      </xsl:when>
      <xsl:when test="pk/@ref">
        <xsl:variable name="ref" select="pk/@ref" />
        <xsl:apply-templates select="/manifest/types/domain[@name=$ref]" mode="get-pk-domain" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:copy-of select="." />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <xsl:template match="domain" mode="get-pk-name">
    <xsl:value-of select="msxsl:node-set($pkdomain)/domain/@name" />
  </xsl:template>

  <xsl:template name="get-element-name">
    <xsl:param name="element" />
    <xsl:param name="prefix" />
    <xsl:param name="suffix" />
    <xsl:choose>
      <xsl:when test="$element/@shortName">
        <xsl:value-of select="concat($prefix, $element/@shortName, $suffix)" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="concat($prefix, $element/@name, $suffix)" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <xsl:template match="field" mode="data-transfer">
    <xsl:text>
            /// &lt;summary /&gt;
#if (!NET_CF)
            [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]</xsl:text>
    <xsl:if test="contains(@name, '_')">
      <xsl:text>
            [SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", MessageId="Member")]</xsl:text>
    </xsl:if>
<xsl:text>
#endif
            public </xsl:text>
    <xsl:apply-templates select="." mode="get-type" />
    <xsl:text> </xsl:text>
    <xsl:value-of select="@name" />
    <xsl:text>;</xsl:text>
  </xsl:template>
    
  <xsl:template match="property" mode="public">
    <xsl:variable name="t" select="@type" />
    <xsl:variable name="domain" select="/manifest/types/domain[@name=$t]" />
    <xsl:text>

        /// &lt;summary /&gt;</xsl:text>
    <xsl:if test="@size&gt;0">
<xsl:text>
        [StringLengthRule(</xsl:text>
      <xsl:value-of select="@size" />
      <xsl:text>)]</xsl:text>
    </xsl:if>
    <xsl:if test="@required='true'">
<xsl:text>
        [NotNullRule]</xsl:text>
    </xsl:if>
<xsl:text>
#if (!NET_CF)
        [DataObjectField(false, false, </xsl:text>
    <xsl:choose>
      <xsl:when test="@required='true'">
        <xsl:text>false</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>true</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
<xsl:text>)]
#endif
        </xsl:text>
    <xsl:value-of select="accessor/@getter" />
    <xsl:text> </xsl:text>
    <xsl:apply-templates select="." mode="get-type" />
    <xsl:text> </xsl:text>
    <xsl:value-of select="@name" />
    <xsl:text>
        {
            get
            {
                return _</xsl:text>
    <xsl:value-of select="@name" />
    <xsl:text>Property;
            }</xsl:text>
    <xsl:if test="accessor/@setter!='none'">
      <xsl:text>
            </xsl:text>
        <xsl:if test="accessor/@setter!=accessor/@getter">
          <xsl:value-of select="accessor/@setter" />
          <xsl:text> </xsl:text>
        </xsl:if>
        <xsl:text>set
            {
                if (_</xsl:text>
          <xsl:value-of select="@name" />
          <xsl:text>Property!=value)
                {
                    _</xsl:text>
          <xsl:value-of select="@name" />
          <xsl:text>Property=value;
                    RaisePropertyChanged("</xsl:text>
          <xsl:value-of select="@name" />
          <xsl:text>");
                }
            }</xsl:text>
    </xsl:if>
    <xsl:text>
        }</xsl:text>
  </xsl:template>

  <xsl:template match="property" mode="default">
    <xsl:variable name="t" select="@type" />
    <xsl:variable name="domain" select="/manifest/types/domain[@name=$t]" />
    <xsl:text>

        /// &lt;summary /&gt;
        private </xsl:text>
    <xsl:apply-templates select="." mode="get-type" />
    <xsl:text> _</xsl:text>
    <xsl:value-of select="@name" />
    <xsl:text>Property
        {</xsl:text>
    <xsl:choose>
      <xsl:when test="$domain">
        <xsl:text>
            get
            {
                Load(true);
                return _</xsl:text>
    <xsl:value-of select="@name" />
    <xsl:text>;
            }</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>
            get
            {
                Load(true);
                return Data.</xsl:text>
        <xsl:value-of select="@field" />
        <xsl:text>;
            }</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:if test="accessor/@setter!='none'">
    <xsl:choose>
      <xsl:when test="$domain">
        <xsl:text>
            set
            {</xsl:text>
        <xsl:if test="$domain">
          <xsl:text>
                _Load</xsl:text>
          <xsl:value-of select="@name" />
          <xsl:text>(true);</xsl:text>
        </xsl:if>
        <xsl:text>
                if (_</xsl:text>
        <xsl:value-of select="@name" />
        <xsl:text>!=value)
                {
                    if ((_</xsl:text>
        <xsl:value-of select="@name" />
        <xsl:text>!=null) &amp;&amp; (_</xsl:text>
        <xsl:value-of select="@name" />
        <xsl:text>.InternalIsNew))
                        _</xsl:text>
        <xsl:value-of select="@name" />
        <xsl:text>.Saved-=_</xsl:text>
        <xsl:value-of select="@name" />
        <xsl:text>_Saved;
                    _</xsl:text>
        <xsl:value-of select="@name" />
        <xsl:text>=value;</xsl:text>
        <xsl:variable name="f" select="@field" />
        <xsl:choose>
          <xsl:when test="../../data/field[@name=$f]/@nullable='true'">
            <xsl:text>
                    if (value!=null)
                    {
                        if (_</xsl:text>
            <xsl:value-of select="@name" />
            <xsl:text>.InternalIsNew)
                            _</xsl:text>
            <xsl:value-of select="@name" />
            <xsl:text>.Saved+=_</xsl:text>
            <xsl:value-of select="@name" />
            <xsl:text>_Saved;
                        else
                            Data.</xsl:text>
            <xsl:value-of select="@field" />
            <xsl:text>=(</xsl:text>
            <xsl:value-of select="../../data/field[@name=$f]/@type" />
            <xsl:text>?)value.GetId();
                    } else
                      Data.</xsl:text>
            <xsl:value-of select="@field" />
            <xsl:text>=null;</xsl:text>
          </xsl:when>
          <xsl:otherwise>
            <xsl:text>
                    if (value!=null)
                    {
                        if (_</xsl:text>
            <xsl:value-of select="@name" />
            <xsl:text>.InternalIsNew)
                            _</xsl:text>
            <xsl:value-of select="@name" />
            <xsl:text>.Saved+=_</xsl:text>
            <xsl:value-of select="@name" />
            <xsl:text>_Saved;
                        else
                            Data.</xsl:text>
            <xsl:value-of select="@field" />
            <xsl:text>=(</xsl:text>
            <xsl:value-of select="../../data/field[@name=$f]/@type" />
            <xsl:text>)value.GetId();
                    }</xsl:text>
          </xsl:otherwise>
        </xsl:choose>
        <xsl:text>
                }
            }</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>
            set
            {</xsl:text>
        <xsl:if test="$domain">
          <xsl:text>
                _Load</xsl:text>
          <xsl:value-of select="@name" />
          <xsl:text>(true);</xsl:text>
        </xsl:if>
        <xsl:text>
                if (Data.</xsl:text>
        <xsl:value-of select="@field" />
        <xsl:text>!=value)
                {
                    Data.</xsl:text>
        <xsl:value-of select="@field" />
        <xsl:text>=value;
                }
            }</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
    </xsl:if>
    <xsl:text>
        }</xsl:text>
  </xsl:template>
  
  <xsl:template match="property" mode="member">
    <xsl:variable name="t" select="@type" />
    <xsl:variable name="domain" select="/manifest/types/domain[@name=$t]" />
    <xsl:if test="$domain">
      <xsl:text>
        /// &lt;summary /&gt;
        private </xsl:text>
      <xsl:value-of select="@type" />
      <xsl:text> _</xsl:text>
      <xsl:value-of select="@name" />
      <xsl:text>;</xsl:text>
    </xsl:if>
  </xsl:template>
  
  <xsl:template match="property" mode="load-method">
    <xsl:variable name="t" select="@type" />
    <xsl:variable name="domain" select="/manifest/types/domain[@name=$t]" />
    <xsl:if test="$domain">
      <xsl:variable name="f" select="@field" />
      <xsl:variable name="nul" select="../../data/field[@name=$f]/@nullable='true'" />
      <xsl:text>

        /// &lt;summary /&gt;
        private void _Load</xsl:text>
      <xsl:value-of select="@name" />
      <xsl:text>(bool lazyload)
        {
            if (IsNew)
                return;

            if </xsl:text>
      <xsl:if test="$nul">
        <xsl:text>(</xsl:text>
      </xsl:if>
      <xsl:text>(_</xsl:text>
      <xsl:value-of select="@name" />
      <xsl:text>==null)</xsl:text>
      <xsl:if test="$nul">
        <xsl:text> &amp;&amp; (Data.</xsl:text>
        <xsl:value-of select="@field" />
        <xsl:text>.HasValue))</xsl:text>
      </xsl:if>
      <xsl:text>
                _</xsl:text>
      <xsl:value-of select="@name" />
      <xsl:text>=((</xsl:text>
      <xsl:call-template name="get-imapper-name">
        <xsl:with-param name="domain" select="$domain" />
      </xsl:call-template>
      <xsl:text>)DataMappers[typeof(</xsl:text>
      <xsl:value-of select="@type" />
      <xsl:text>)]).Find(Data.</xsl:text>
      <xsl:value-of select="@field" />
      <xsl:text>, DataMappers);
        }

        /// &lt;summary /&gt;
        private void _</xsl:text>
      <xsl:value-of select="@name" />
      <xsl:text>_Saved(object sender, PersistenceEventArgs e)
        {
            </xsl:text>
      <xsl:value-of select="../../data/field[@name=$f]/@type" />
      <xsl:if test="../../data/field[@name=$f]/@nullable='true'">
        <xsl:text>?</xsl:text>
      </xsl:if>
      <xsl:text> id=((</xsl:text>
      <xsl:value-of select="@type" />
      <xsl:text>)sender).GetId().Value;
            if (Data.</xsl:text>
      <xsl:value-of select="@field" />
      <xsl:text>!=id)
            {
                Data.</xsl:text>
      <xsl:value-of select="@field" />
      <xsl:text>=id;
                IsModified=true;
            }

            ((</xsl:text>
      <xsl:value-of select="@type" />
      <xsl:text>)sender).Saved-=_</xsl:text>
      <xsl:value-of select="@name" />
      <xsl:text>_Saved;
        }</xsl:text>
    </xsl:if>
  </xsl:template>
  
  <xsl:template name="generate-user-file">
    <xsl:text>// $Id$
/*! \file
 * \brief Definition of </xsl:text>
      <xsl:value-of select="$package" />
      <xsl:text>.</xsl:text>
      <xsl:value-of select="$domainName" />
      <xsl:text>.
 *
 * \author $Author$
 * \date $Date$
 * \version $Revision$
 */

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Xml.Serialization;
using Salamanca.DataAccess;
using Salamanca.DataAccess.Collections;
using Salamanca.DataRules;
#if (!NET_CF)
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;
#endif

namespace </xsl:text>
      <xsl:value-of select="$package" />
      <xsl:text>
{



    ///////////////////////////////////////////////////////////////////////////
    ///
    /// &lt;summary /&gt;
    ///
    ///////////////////////////////////////////////////////////////////////////

    </xsl:text>
      <xsl:call-template name="get-visibility" />
      <xsl:text> partial interface </xsl:text>
      <xsl:call-template name="get-icontainer-name" />
      <xsl:text>
    {
    }



    ///////////////////////////////////////////////////////////////////////////
    ///
    /// &lt;summary /&gt;
    ///
    ///////////////////////////////////////////////////////////////////////////

    </xsl:text>
      <xsl:call-template name="get-visibility" />
      <xsl:text> partial interface </xsl:text>
      <xsl:call-template name="get-imapper-name" />
      <xsl:text>:
        IDataMapper
    {
    }



    ///////////////////////////////////////////////////////////////////////////
    ///
    /// &lt;summary /&gt;
    ///
    ///////////////////////////////////////////////////////////////////////////

#if (!NET_CF)
    [Serializable]
    [DataObject]
#endif
    </xsl:text>
      <xsl:call-template name="get-visibility" />
      <xsl:text> partial class </xsl:text>
      <xsl:value-of select="$domainName" />
      <xsl:text>:
        </xsl:text>
      <xsl:choose>
        <xsl:when test="$domain/@extends">
          <xsl:value-of select="$domain/@extends" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:text>DomainEntity&lt;</xsl:text>
          <xsl:apply-templates select="$domain" mode="get-pk-name" />
          <xsl:text>.PrimaryKey, </xsl:text>
          <xsl:value-of select="$domainName" />
          <xsl:text>.DataTransfer&gt;</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
      <xsl:text>
    {</xsl:text>
      <xsl:if test="not($domain/@extends) and not($domain/pk/@ref)">
        <xsl:text>

        /// &lt;summary /&gt;
#if (!NET_CF)
        [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
#endif
        </xsl:text>
        <xsl:call-template name="get-visibility" />
        <xsl:text> partial class PrimaryKey:
            PrimaryKey&lt;</xsl:text>
        <xsl:call-template name="get-pk-type" />
        <xsl:text>&gt;
        {

            /// &lt;summary /&gt;
            public PrimaryKey():
                base()
            {
            }

            /// &lt;summary /&gt;
            public PrimaryKey(</xsl:text>
        <xsl:call-template name="get-pk-type" />
        <xsl:text> key):
                base(key)
            {
            }

        }</xsl:text>
      </xsl:if>
      <xsl:text>

        /// &lt;summary /&gt;
        [SoapType("</xsl:text>
      <xsl:value-of select="$domainName" />
      <xsl:text>Data", "</xsl:text>
      <xsl:value-of select="$domain/data/@namespace" />
      <xsl:text>")]
        [XmlType("</xsl:text>
      <xsl:value-of select="$domainName" />
      <xsl:text>Data", Namespace="</xsl:text>
      <xsl:value-of select="$domain/data/@namespace" />
      <xsl:text>")]
#if (!NET_CF)
        [Serializable]
        [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
#endif
        </xsl:text>
      <xsl:call-template name="get-visibility" />
      <xsl:if test="$domain/@extends">
        <xsl:text> new</xsl:text>
      </xsl:if>
      <xsl:text> partial class DataTransfer:
            </xsl:text>
      <xsl:choose>
        <xsl:when test="$domain/@extends">
          <xsl:value-of select="$domain/@extends" />
          <xsl:text>.DataTransfer</xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <xsl:text>IDataTransferObject</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
      <xsl:text>
        {
        }</xsl:text>
      <xsl:text>

        /// &lt;summary /&gt;
        public </xsl:text>
      <xsl:value-of select="$domainName" />
      <xsl:text>():
            base()
        {
        }

        /// &lt;summary /&gt;
        public </xsl:text>
      <xsl:value-of select="$domainName" />
      <xsl:text>(DataMapperCollection dataMappers):
            base(dataMappers)
        {
        }

#if (!NET_CF)
        /// &lt;summary /&gt;
        protected </xsl:text>
      <xsl:value-of select="$domainName" />
      <xsl:text>(SerializationInfo info, StreamingContext context):
            base(info, context)
        {
        }
#endif</xsl:text>
      <xsl:if test="count($domain/interface/property[@type=/manifest/types/domain/@name]) &gt; 0">
        <xsl:text>

        /// &lt;summary /&gt;
        protected override void OnSaving(PersistenceEventArgs e)
        {</xsl:text>
        <xsl:for-each select="$domain/interface/property[@type=/manifest/types/domain/@name]">
          <xsl:text>
            if (_</xsl:text>
          <xsl:value-of select="@name" />
          <xsl:text>!=null)
              ((IPersistent)_</xsl:text>
          <xsl:value-of select="@name" />
          <xsl:text>).Save(e.Context);</xsl:text>
        </xsl:for-each>
        <xsl:text>

            base.OnSaving(e);
        }

        /// &lt;summary /&gt;
        public override void Load(bool lazyLoad)
        {
            base.Load(lazyLoad);

            if (!IsNew)
            {</xsl:text>
        <xsl:for-each select="$domain/interface/property[@type=/manifest/types/domain/@name]">
          <xsl:text>
                _Load</xsl:text>
          <xsl:value-of select="@name" />
          <xsl:text>(lazyLoad);</xsl:text>
        </xsl:for-each>
        <xsl:text>
            }
        }

        /// &lt;summary /&gt;
        public override void Unload()
        {
            base.Unload();
</xsl:text>
        <xsl:for-each select="$domain/interface/property[@type=/manifest/types/domain/@name]">
          <xsl:text>
            _</xsl:text>
          <xsl:value-of select="@name" />
          <xsl:text>=null;</xsl:text>
        </xsl:for-each>
        <xsl:text>
        }</xsl:text>
      </xsl:if>
      <xsl:apply-templates select="$domain/interface/property" mode="public" />
      <xsl:text>

    }
}
</xsl:text>
  </xsl:template>
  
  <xsl:template name="generate-model-file">
    <xsl:variable name="src">
      <xsl:text>// $Id$
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.Xml.Serialization;
using Salamanca.DataAccess;
using Salamanca.DataAccess.Collections;
using Salamanca.DataRules;
#if (!NET_CF)
using System.Diagnostics.CodeAnalysis;
#endif

namespace </xsl:text>
      <xsl:value-of select="$package" />
      <xsl:text>
{

    /// &lt;summary /&gt;
    partial interface </xsl:text>
      <xsl:call-template name="get-icontainer-name" />
      <xsl:text>
    {
        /// &lt;summary /&gt;
      </xsl:text>
      <xsl:value-of select="$domainName" />
      <xsl:text> </xsl:text>
      <xsl:value-of select="$domainName" />
      <xsl:text>
        {
            get;
            set;
        }

    }

    /// &lt;summary /&gt;
    partial interface </xsl:text>
      <xsl:call-template name="get-imapper-name" />
      <xsl:text>
    {

        /// &lt;summary /&gt;
        </xsl:text>
      <xsl:value-of select="$domainName" />
      <xsl:text> Find(</xsl:text>
      <xsl:apply-templates select="$domain" mode="get-pk-name" />
      <xsl:text>.PrimaryKey key, DataMapperCollection dataMappers);
        /// &lt;summary /&gt;
        DomainEntityKeyedCollection&lt;</xsl:text>
      <xsl:value-of select="$domainName" />
      <xsl:text>&gt; FindAll(DataMapperCollection dataMappers);

    }

    /// &lt;summary /&gt;
    partial class </xsl:text>
      <xsl:value-of select="$domainName" />
      <xsl:text>
    {</xsl:text>

      <xsl:if test="not($domain/@extends) and not($domain/pk/@ref)">
        <xsl:text>

        /// &lt;summary /&gt;
        partial class PrimaryKey
        {</xsl:text>
        <xsl:if test="count($domain/pk/field) &gt; 1">
          <xsl:text>
            /// &lt;summary /&gt;
            </xsl:text>
          <xsl:call-template name="get-visibility" />
          <xsl:text> struct Key
            {</xsl:text>
          <xsl:apply-templates select="$domain/data/field[@name=$domain/pk/field/@name]" mode="data-transfer" />
          <xsl:text>
          
                /// &lt;summary /&gt;
                public Key(</xsl:text>
          <xsl:for-each select="$domain/data/field[@name=$domain/pk/field/@name]">
            <xsl:value-of select="@type" />
            <xsl:text> </xsl:text>
            <xsl:value-of select="nyext:toLower(@name)" />
            <xsl:if test="position()!=last()">
              <xsl:text>,</xsl:text>
            </xsl:if>
          </xsl:for-each>
          <xsl:text>)
                {</xsl:text>
          <xsl:for-each select="$domain/data/field[@name=$domain/pk/field/@name]">
            <xsl:text>
                </xsl:text>
            <xsl:value-of select="@name" />
            <xsl:text>=</xsl:text>
            <xsl:value-of select="nyext:toLower(@name)" />
            <xsl:text>;</xsl:text>
          </xsl:for-each>
          <xsl:text>
                }

                /// &lt;summary /&gt;
                public override string ToString()
                {
                    return string.Format(
                        CultureInfo.CurrentCulture,
                        "</xsl:text>
          <xsl:for-each select="$domain/data/field[@name=$domain/pk/field/@name]">
            <xsl:text>{</xsl:text>
            <xsl:value-of select="position()-1" />
            <xsl:text>}</xsl:text>
            <xsl:if test="position()!=last()">
              <xsl:text>|</xsl:text>
            </xsl:if>
          </xsl:for-each>
          <xsl:text>",</xsl:text>
          <xsl:for-each select="$domain/data/field[@name=$domain/pk/field/@name]">
            <xsl:text>
                        </xsl:text>
            <xsl:value-of select="@name" />
            <xsl:if test="position()!=last()">
              <xsl:text>,</xsl:text>
            </xsl:if>
          </xsl:for-each>
          <xsl:text>
                    );
                }
            }
</xsl:text>
        </xsl:if>
        <xsl:text>
            /// &lt;summary /&gt;
            public static implicit operator PrimaryKey(</xsl:text>
        <xsl:call-template name="get-pk-type" />
        <xsl:text> key)
            {
                return new PrimaryKey(key);
            }

            /// &lt;summary /&gt;
            public static explicit operator </xsl:text>
        <xsl:call-template name="get-pk-type" />
        <xsl:text>(PrimaryKey key)
            {
                return key.Value;
            }</xsl:text>
<!--        <xsl:if test="count($domain/pk/field)=1">
          <xsl:text>

            /// &lt;summary /&gt;
            public static explicit operator PrimaryKey(object value)
            {
                return new PrimaryKey((</xsl:text>
          <xsl:call-template name="get-pk-type" />
          <xsl:text>)Convert.ChangeType(value, typeof(</xsl:text>
          <xsl:call-template name="get-pk-type" />
          <xsl:text>));
            }</xsl:text>
        </xsl:if> -->
        <xsl:text>

        }</xsl:text>
      </xsl:if>
      <xsl:text>

        /// &lt;summary /&gt;
        </xsl:text>
      <xsl:if test="$domain/@extends">
        <xsl:text>new </xsl:text>
      </xsl:if>
      <xsl:text>partial class DataTransfer
        {</xsl:text>
      <xsl:apply-templates select="$domain/data/field" mode="data-transfer" />
      <xsl:if test="not($domain/@extends)">
        <xsl:text>

            /// &lt;summary /&gt;
            public object Clone()
            {
                return MemberwiseClone();
            }</xsl:text>
      </xsl:if>
      <xsl:text>

        }</xsl:text>
      <xsl:if test="not($domain/@extends)">
        <xsl:text>

        /// &lt;summary /&gt;
        protected override </xsl:text>
          <xsl:apply-templates select="$domain" mode="get-pk-name" />
          <xsl:text>.PrimaryKey CreateId()
        {
            return new </xsl:text>
          <xsl:apply-templates select="$domain" mode="get-pk-name" />
          <xsl:text>.PrimaryKey(</xsl:text>
          <xsl:choose>
            <xsl:when test="count(msxsl:node-set($pkdomain)/domain/pk/field) &gt; 1">
              <xsl:text>new </xsl:text>
              <xsl:apply-templates select="$domain" mode="get-pk-name" />
              <xsl:text>.PrimaryKey.Key(</xsl:text>
              <xsl:for-each select="msxsl:node-set($pkdomain)/domain/pk/field">
                <xsl:text>Data.</xsl:text>
                <xsl:value-of select="@name" />
                <xsl:if test="position()!=last()">
                  <xsl:text>, </xsl:text>
                </xsl:if>
              </xsl:for-each>
              <xsl:text>)</xsl:text>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>Data.</xsl:text>
              <xsl:value-of select="msxsl:node-set($pkdomain)/domain/pk/field/@name" />
            </xsl:otherwise>
          </xsl:choose>
          <xsl:text>);
        }

        /// &lt;summary /&gt;
        internal </xsl:text>
          <xsl:apply-templates select="$domain" mode="get-pk-name" />
          <xsl:text>.PrimaryKey GetId()
        {
            return Id;
        }

        /// &lt;summary /&gt;
        internal void SetId(</xsl:text>
            <xsl:call-template name="get-pk-type" />
            <xsl:text> id)
        {</xsl:text>
            <xsl:choose>
              <xsl:when test="count(msxsl:node-set($pkdomain)/domain/pk/field) &gt; 1">
                <xsl:for-each select="msxsl:node-set($pkdomain)/domain/pk/field">
                  <xsl:text>
            Data.</xsl:text>
                  <xsl:value-of select="@name" />
                  <xsl:text>=id.</xsl:text>
                  <xsl:value-of select="@name" />
                  <xsl:text>;</xsl:text>
              </xsl:for-each>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>
            Data.</xsl:text>
              <xsl:value-of select="msxsl:node-set($pkdomain)/domain/pk/field/@name" />
              <xsl:text>=id;</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
          <xsl:text>
        }</xsl:text>
        </xsl:if>
        <xsl:if test="$domain/@extends">
          <xsl:text>

        /// &lt;summary /&gt;
        protected new DataTransfer Data
        {
            get
            {
                return (DataTransfer)base.Data;
            }
            set
            {
                base.Data=value;
            }
        }</xsl:text>
        </xsl:if>
        <xsl:text>


        /// &lt;summary /&gt;
#if (!NET_CF)
        [DataObjectMethod(DataObjectMethodType.Select, false)]
#endif
        public static </xsl:text>
      <xsl:if test="$domain/@extends">
        <xsl:text>new </xsl:text>
      </xsl:if>
      <xsl:value-of select="$domainName" />
      <xsl:text> Find(</xsl:text>
      <xsl:apply-templates select="$domain" mode="get-pk-name" />
      <xsl:text>.PrimaryKey key, DataMapperCollection dataMappers)
        {
            return ((</xsl:text>
      <xsl:call-template name="get-imapper-name" />
      <xsl:text>)dataMappers[typeof(</xsl:text>
      <xsl:value-of select="$domainName" />
      <xsl:text>)]).Find(key, dataMappers);
        }

        /// &lt;summary /&gt;
#if (!NET_CF)
        [DataObjectMethod(DataObjectMethodType.Select, true)]
#endif
        public static </xsl:text>
      <xsl:if test="$domain/@extends">
        <xsl:text>new </xsl:text>
      </xsl:if>
      <xsl:text>IList&lt;</xsl:text>
      <xsl:value-of select="$domainName" />
      <xsl:text>&gt; FindAll(DataMapperCollection dataMappers)
        {
            return ((</xsl:text>
      <xsl:call-template name="get-imapper-name" />
      <xsl:text>)dataMappers[typeof(</xsl:text>
      <xsl:value-of select="$domainName" />
      <xsl:text>)]).FindAll(dataMappers);
        }</xsl:text>
      <xsl:apply-templates select="$domain/interface/property" mode="load-method" />
      <xsl:if test="not($domain/@extends)">
        <xsl:text>

        /// &lt;summary /&gt;
        internal bool InternalIsNew
        {
            get
            {
                return IsNew;
            }
        }</xsl:text>
      </xsl:if>
      <xsl:apply-templates select="$domain/interface/property" mode="default" />
      <xsl:text>
</xsl:text>
      <xsl:apply-templates select="$domain/interface/property" mode="member" />
      <xsl:if test="not($domain/@extends)">
        <xsl:text>

        /// &lt;summary /&gt;
        public static readonly IdentityMap&lt;</xsl:text>
          <xsl:apply-templates select="$domain" mode="get-pk-name" />
          <xsl:text>.PrimaryKey, </xsl:text>
        <xsl:value-of select="$domainName" />
        <xsl:text>&gt; IdentityMap=new IdentityMap&lt;</xsl:text>
          <xsl:apply-templates select="$domain" mode="get-pk-name" />
          <xsl:text>.PrimaryKey, </xsl:text>
        <xsl:value-of select="$domainName" />
        <xsl:text>&gt;();</xsl:text>
      </xsl:if>
      <xsl:text>

    }

}
</xsl:text>
    </xsl:variable>
    <xsl:value-of select="nyext:generateFile($src, nyext:combinePath($outdir, concat(nyext:getModelFileName($name), '.cs')))" />
  </xsl:template>

  <xsl:template match="/">
    <xsl:call-template name="generate-user-file" />
    <xsl:call-template name="generate-model-file" />
  </xsl:template>
</xsl:stylesheet>
